import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.condition.RequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.*;
import java.util.Map;
* ClassName: CustomRequestMappingHandlerMapping<br/>
* Function: TODO ADD FUNCTION(可选)<br/>
* Reason: TODO ADD REASON(可选)<br/>
* Date: 2017-10-31 15:13<br/>
*
* @author zoro
*/
public class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
@Override
protected RequestCondition<ApiVesrsionCondition> getCustomTypeCondition(Class<?> handlerType) {
ApiVersion apiVersion = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);
return createCondition(apiVersion);
}
@Override
protected RequestCondition<ApiVesrsionCondition> getCustomMethodCondition(Method method) {
ApiVersion apiVersion = AnnotationUtils.findAnnotation(method, ApiVersion.class);
return createCondition(apiVersion);
}
private RequestCondition<ApiVesrsionCondition> createCondition(ApiVersion apiVersion) {
return apiVersion == null ? null : new ApiVesrsionCondition(apiVersion.value());
}
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo info = this.createRequestMappingInfo(method, null);
if (info != null) {
ApiVersion apiVersion = (ApiVersion) AnnotatedElementUtils.findMergedAnnotation(method, ApiVersion.class);
RequestMappingInfo typeInfo = this.createRequestMappingInfo(handlerType, apiVersion);
if (typeInfo != null) {
info = typeInfo.combine(info);
}
}
return info;
}
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element, ApiVersion apiVersion) {
RequestMapping requestMapping = (RequestMapping) AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
RequestCondition<?> condition = element instanceof Class ? this.getCustomTypeCondition((Class)element) : this.getCustomMethodCondition((Method)element);
if (element instanceof Class && null != apiVersion) {
try {
InvocationHandler invocationHandler = Proxy.getInvocationHandler(requestMapping);
Field field = invocationHandler.getClass().getDeclaredField("valueCache");
field.setAccessible(true);
Map map = (Map) field.get(invocationHandler);
String[] paths = new String[requestMapping.path().length];
for (int i = 0; i< requestMapping.path().length; i++) {
paths[i] = requestMapping.path()[i].replace("{version}", "v".concat(apiVersion.value()));
}
map.put("path", paths);
String[] values = new String[requestMapping.value().length];
for (int i = 0; i< requestMapping.value().length; i++) {
values[i] = requestMapping.value()[i].replace("{version}", "v".concat(apiVersion.value()));
}
map.put("value", values);
} catch (Exception e) {
e.printStackTrace();
}
}
return requestMapping != null ? this.createRequestMappingInfo(requestMapping, condition) : null;
}
}